﻿<i id="abp-title" data-title="Unit Testing with Entity Framework and xUnit Effort"></i>
 
<ul class="download">
	<li>Get the source code from the <a href="https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/SimpleTaskSystem">GitHub repository.</a></li>
</ul>

<h2 class="abp-invisible">Contents</h2>

<ul class="abp-invisible">
	<li><a href="#ArticleIntroduction">Introduction</a></li>
	<li><a href="#ArticleTestProject">Creating a test project</a></li>
	<li><a href="#ArticlePrepareBase">Preparing a base test class</a></li>
	<li><a href="#ArticleFirstTest">Creating first test</a></li>
	<li><a href="#ArticleTestExceptions">Testing exceptions</a></li>
	<li><a href="#ArticleUsingRepositories">Using repositories in tests</a></li>
	<li><a href="#ArticleTestAsync">Testing async methods</a></li>
	<li><a href="#ArticleSummary">Summary</a></li>
	<li><a href="#ArticleHistory">Article History</a></li>
</ul>

<h2 id="ArticleIntroduction">Introduction</h2>

<p>In this article, I&#39;ll show how to create unit tests for <a href="http://www.aspnetboilerplate.com/" target="_blank">ASP.NET Boilerplate</a> based projects. Instead of creating a new application to be tested, I&#39;ll use the same application developed in <a href="http://www.codeproject.com/Articles/791740/Using-AngularJs-ASP-NET-MVC-Web-API-and-EntityFram" data-abp-href="/Pages/Articles/Introduction-With-AspNet-MVC-Web-API-EntityFramework-and-AngularJs/index.html" target="_blank"> this article</a> (<em>Using AngularJS, ASP.NET MVC, Web API and EntityFramework to build NLayered Single Page Web Applications</em>). Solution structure is like that:</p>

<p><img alt="Solution structrure" height="191" src="solution-structure.png" width="272" /></p>

<p>We will test <strong>Application Services</strong> of the project. It includes SimpleTaskSystem.<strong>Core, </strong>SimpleTaskSystem.<strong>Application </strong>and SimpleTaskSystem.<strong>EntityFramework </strong>projects. You can read <a href="http://www.codeproject.com/Articles/791740/Using-AngularJs-ASP-NET-MVC-Web-API-and-EntityFram" data-abp-href="/Pages/Articles/Introduction-With-AspNet-MVC-Web-API-EntityFramework-and-AngularJs/index.html" target="_blank">this article</a> to see how to build this application. Here, I&#39;ll focus on testing.&nbsp;</p>

<h2 id="ArticleTestProject">Create a test project</h2>

<p>I created a new <strong>Class Library</strong> project named <strong> SimpleTaskSystem.Test</strong> and added following nuget packages:</p>

<ul>
	<li><strong>Abp.TestBase</strong>: Provides some base classes to make testing easier for ABP based projects.</li>
	<li><strong>Abp.EntityFramework</strong>: We use EntityFramework 6.x as ORM.</li>
	<li><strong>Effort.EF6</strong>: Makes it possible to create a fake, in-memory database for EF that is easy to use.</li>
	<li><strong>xunit</strong>: The testing framework we&#39;ll use. Also, added <strong>xunit.runner.visualstudio</strong> package to run tests in Visual Studio. This package was pre-release when I writing this article. So, I selected &#39;Include Prerelease&#39; in nuget package manager dialog.</li>
	<li><strong>Shouldly</strong>: This library makes easy to write assertions.</li>
</ul>

<p>When we add these packages, their dependencies will also be added automatically. Lastly, we should add reference to SimpleTaskSystem.<strong>Application</strong>, SimpleTaskSystem.<strong>Core </strong>and SimpleTaskSystem.<strong>EntityFramework </strong>assemblies since we will test these projects.</p>

<h2 id="ArticlePrepareBase">Preparing a base test class</h2>

<p>To create test classes easier, I&#39;ll create a base class that prepares a fake database connection:</p>

<pre>
/// &lt;summary&gt;
/// This is base class for all our test classes.
/// It prepares ABP system, modules and a fake, in-memory database.
/// Seeds database with initial data (&lt;see cref=&quot;SimpleTaskSystemInitialDataBuilder&quot;/&gt;).
/// Provides methods to easily work with DbContext.
/// &lt;/summary&gt;
public abstract class SimpleTaskSystemTestBase : AbpIntegratedTestBase&lt;SimpleTaskSystemTestModule&gt;
{
    protected SimpleTaskSystemTestBase()
    {
        //Seed initial data
        UsingDbContext(context =&gt; new SimpleTaskSystemInitialDataBuilder().Build(context));
    }

    protected override void PreInitialize()
    {
        //Fake DbConnection using Effort!
        LocalIocManager.IocContainer.Register(
            Component.For&lt;DbConnection&gt;()
                .UsingFactoryMethod(Effort.DbConnectionFactory.CreateTransient)
                .LifestyleSingleton()
            );

        base.PreInitialize();
    }

    public void UsingDbContext(Action&lt;SimpleTaskSystemDbContext&gt; action)
    {
        using (var context = LocalIocManager.Resolve&lt;SimpleTaskSystemDbContext&gt;())
        {
            context.DisableAllFilters();
            action(context);
            context.SaveChanges();
        }
    }

    public T UsingDbContext&lt;T&gt;(Func&lt;SimpleTaskSystemDbContext, T&gt; func)
    {
        T result;

        using (var context = LocalIocManager.Resolve&lt;SimpleTaskSystemDbContext&gt;())
        {
            context.DisableAllFilters();
            result = func(context);
            context.SaveChanges();
        }

        return result;
    }
}</pre>

<p>This base class extends <strong>AbpIntegratedTestBase</strong>. It&#39;s a base class which initializes the ABP system. Defines <strong>LocalIocContainer</strong> property, that is a <strong>IIocManager</strong> object. Each test will work with it&#39;s dedicated IIocManager. Thus, tests will be isolated from each other.</p>

<p>We should create a module dedicated for tests. It&#39;s <strong>SimpleTaskSystemTestModule</strong> here:</p>

<pre lang="cs">
[DependsOn(
        typeof(SimpleTaskSystemDataModule),
        typeof(SimpleTaskSystemApplicationModule),
        typeof(AbpTestBaseModule)
    )]
public class SimpleTaskSystemTestModule : AbpModule
{
        
}</pre>

<p>This module only defines depended modules, which will be tested and the AbpTestBaseModule.</p>

<p>In the SimpleTaskSystemTestBase&#39;s PreInitialize method, we&#39;re registering <strong>DbConnection</strong> to dependency injection system using <strong>Effort</strong> (PreInitialize method is used to run some code just befor ABP initialized). We registered it as Singleton (for LocalIocConainer). Thus, same database (and connection) will be used in a test even we create more than one DbContext in same test. <strong>SimpleTaskSystemDbContext</strong> must have a constructor getting DbConnection in order to use this in-memory database. So, I added the constructor below that accepts a DbConnection:</p>

<pre>
public class SimpleTaskSystemDbContext : AbpDbContext
{
    public virtual IDbSet&lt;Task&gt; Tasks { get; set; }
    public virtual IDbSet&lt;Person&gt; People { get; set; }

    public SimpleTaskSystemDbContext()
        : base(&quot;Default&quot;)
    {

    }

    public SimpleTaskSystemDbContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {
            
    }

    //This constructor is used in tests
    public SimpleTaskSystemDbContext(DbConnection connection)
        : base(connection, true)
    {

    }
}</pre>

<p>In the constructor of SimpleTaskSystemTestBase, we&#39;re also creating an <strong>initial data</strong> in the database. This is important, since some tests require a data present in the database. <strong>SimpleTaskSystemInitialDataBuilder</strong> class fills database as shown below:</p>

<pre>
public class SimpleTaskSystemInitialDataBuilder
{
    public void Build(SimpleTaskSystemDbContext context)
    {
        //Add some people            
        context.People.AddOrUpdate(
            p =&gt; p.Name,
            new Person {Name = &quot;Isaac Asimov&quot;},
            new Person {Name = &quot;Thomas More&quot;},
            new Person {Name = &quot;George Orwell&quot;},
            new Person {Name = &quot;Douglas Adams&quot;}
            );
        context.SaveChanges();

        //Add some tasks
        context.Tasks.AddOrUpdate(
            t =&gt; t.Description,
            new Task
            {
                Description = &quot;my initial task 1&quot;
            },
            new Task
            {
                Description = &quot;my initial task 2&quot;,
                State = TaskState.Completed
            },
            new Task
            {
                Description = &quot;my initial task 3&quot;,
                AssignedPerson = context.People.Single(p =&gt; p.Name == &quot;Douglas Adams&quot;)
            },
            new Task
            {
                Description = &quot;my initial task 4&quot;,
                AssignedPerson = context.People.Single(p =&gt; p.Name == &quot;Isaac Asimov&quot;),
                State = TaskState.Completed
            });
        context.SaveChanges();
    }
}</pre>

<p>SimpleTaskSystemTestBase&#39;s UsingDbContext methods makes it easier to create DbContextes when we need to directly use DbContect to work with database. In constructor, we used it. Also, we will see how to use it in tests.</p>

<p>All our test classes will be inherited from SimpleTaskSystemTestBase. Thus, all tests will be started by initializing ABP, using a fake database with an initial data. We can also add common helper methods to this base class in order to make tests easier.</p>

<h2 id="ArticleFirstTest">Creating first test</h2>

<p>We will create first unit test to test <strong>CreateTask</strong> method of <strong>TaskAppService</strong> class. TaskAppService class and CreateTask method are defined as shown below:</p>

<pre>
public class TaskAppService : ApplicationService, ITaskAppService
{
    private readonly ITaskRepository _taskRepository;
    private readonly IRepository&lt;Person&gt; _personRepository;
        
    public TaskAppService(ITaskRepository taskRepository, IRepository&lt;Person&gt; personRepository)
    {
        _taskRepository = taskRepository;
        _personRepository = personRepository;
    }
        
    public void CreateTask(CreateTaskInput input)
    {
        Logger.Info(&quot;Creating a task for input: &quot; + input);

        var task = new Task { Description = input.Description };

        if (input.AssignedPersonId.HasValue)
        {
            task.AssignedPerson = _personRepository.Load(input.AssignedPersonId.Value);
        }

        _taskRepository.Insert(task);
    }

    //...other methods
}</pre>

<p>In unit test, generally, dependencies of testing class is mocked (by creating fake implementations using some mock frameworks like Moq and NSubstitute). This makes unit testing harder, especially when dependencies grows.</p>

<p>We will not do it like that since we&#39;re using dependency injection. All dependencies will be filled automatically by dependency injection with real implementations, not fakes. Only fake thing is the <strong>database</strong>. Actually, this is an <strong>integration test</strong> since it not only tests the TaskAppService, but also tests repositories. Even, we&#39;re testing it with validation, unit of work and other infrastructures of ASP.NET Boilerplate. This is very valuable since we&#39;re testing the application much more realistic.</p>

<p>So, let&#39;s create first test to test CreateTask method.</p>

<pre>
public class TaskAppService_Tests : SimpleTaskSystemTestBase
{
    private readonly ITaskAppService _taskAppService;

    public TaskAppService_Tests()
    {
        //Creating the class which is tested (SUT - Software Under Test)
        _taskAppService = LocalIocManager.Resolve&lt;ITaskAppService&gt;();
    }

    [Fact]
    public void Should_Create_New_Tasks()
    {
        //Prepare for test
        var initialTaskCount = UsingDbContext(context =&gt; context.Tasks.Count());
        var thomasMore = GetPerson(&quot;Thomas More&quot;);

        //Run SUT
        _taskAppService.CreateTask(
            new CreateTaskInput
            {
                Description = &quot;my test task 1&quot;
            });
        _taskAppService.CreateTask(
            new CreateTaskInput
            {
                Description = &quot;my test task 2&quot;,
                AssignedPersonId = thomasMore.Id
            });

        //Check results
        UsingDbContext(context =&gt;
        {
            context.Tasks.Count().ShouldBe(initialTaskCount + 2);
            context.Tasks.FirstOrDefault(t =&gt; t.AssignedPersonId == null &amp;&amp; t.Description == &quot;my test task 1&quot;).ShouldNotBe(null);
            var task2 = context.Tasks.FirstOrDefault(t =&gt; t.Description == &quot;my test task 2&quot;);
            task2.ShouldNotBe(null);
            task2.AssignedPersonId.ShouldBe(thomasMore.Id);
        });
    }

    private Person GetPerson(string name)
    {
        return UsingDbContext(context =&gt; context.People.Single(p =&gt; p.Name == name));
    }
}</pre>

<p>We inherited from <strong>SimpleTaskSystemTestBase</strong> as described before. In a unit test, we should create the object this will be tested. In the constructor, I used <strong>LocalIocManager</strong> (dependency injection manager) to create an <strong>ITaskAppService</strong> (it creates TaskAppService since it implements ITaskAppService). In this way, I got rid of creating mock implementations of dependencies.</p>

<p><strong>Should_Create_New_Tasks</strong> is the test method. It&#39;s decorated with the <strong>Fact</strong> attribute of xUnit. Thus, <strong>xUnit</strong> understand that this is a test method, and it runs the method.</p>

<p>In a test method, we generally follow <strong>AAA</strong> pattern which consists of three steps:</p>

<ol>
	<li><strong>Arrange</strong>: Prepare for the test</li>
	<li><strong>Act</strong>: Run the SUT (software under test - the actual testing code)</li>
	<li><strong>Assert</strong>: Check and verify the result.</li>
</ol>

<p>In Should_Create_New_Tasks method, we will create two tasks, one will be assigned to Thomas More. So, our three steps are:</p>

<ol>
	<li><strong>Arrange</strong>: We get the person (Thomas More) from database to obtain his Id and the current task count in database (Also, we created the TaskAppService in the constructor).</li>
	<li><strong>Act</strong>: We&#39;re creating two tasks using TaskAppService.CreateTask method.</li>
	<li><strong>Assert</strong>: We&#39;re checking if task count increased by 2. We&#39;re also trying to get created tasks from database to see if they are correctly inserted to the database.</li>
</ol>

<p>Here, UsingDbContext method helps us while working directly with DbContext. If this test success, we understand that CreateTask method can create Tasks if we supply valid inputs. Also, repository is working since it inserted Tasks to the database.</p>

<p>To run tests, we&#39;re opening Visual Studio <strong>Test Explorer</strong> by selecting <strong>TEST\Windows\Test Explorer</strong>:</p>

<p><img alt="Open Visual Studio Test Explorer" height="219" src="opening-vs-test-explorer.png" width="454" /></p>

<p>Then we&#39;re clicking &#39;<strong>Run All</strong>&#39; link in the Test Explorer. It finds and runs all test in the solution:</p>

<p><img alt="Running first unit test using Visual Studio Test Explorer" height="179" src="running-fist-test.png" width="504" /></p>

<p>As shown above, our first unit test is passed. Congratulations! A test will fail if testing or tester code is incorrect. Assume that we have forgotten to assign creating task to given person (To test it, comment out the related lines in TaskAppService.CreateTask method). When we run test, it will fail:</p>

<p><img alt="Failing test" height="107" src="first-test-failed.png" width="483" /></p>

<p><strong>Shouldly</strong> library makes fail messages clearer. It also makes it easy to write assertions. Compare xUnit&#39;s <strong>Assert.Equal</strong> with Shouldly&#39;s <strong>ShouldBe</strong> extension method:</p>

<pre>
Assert.Equal(thomasMore.Id, task2.AssignedPersonId); //Using xunit&#39;s Assert
task2.AssignedPersonId.ShouldBe(thomasMore.Id); //Using Shouldly
</pre>

<p>I think the second one is more easy and natual to write and read. Shouldly have many other extension methods to make our life easier. See it&#39;s documentation.</p>

<h2 id="ArticleTestExceptions">Testing exceptions</h2>

<p>I want to create a second test for the CreateTask method. But, this time with an <strong>invalid input</strong>:</p>

<pre>
[Fact]
public void Should_Not_Create_Task_Without_Description()
{
    //Description is not set
    Assert.Throws&lt;AbpValidationException&gt;(() =&gt; _taskAppService.CreateTask(new CreateTaskInput()));
}</pre>

<p>I expect that CreateTask method throws <strong>AbpValidationException</strong> if I don&#39;t set <strong>Description</strong> for creating task. Because Description property is marked as <strong>Required </strong>in <strong>CreateTaskInput </strong>DTO class (see source codes). This test success if CreateTask throws the exception, otherwise fails. Note that; validating input and throwing exception are made by ASP.NET Boilerplate infrastructure.</p>

<h2 id="ArticleUsingRepositories">Using repositories in tests</h2>

<p>I&#39;ll test to assign a task from one person to another:</p>

<pre>
//Trying to assign a task of Isaac Asimov to Thomas More
[Fact]
public void Should_Change_Assigned_People()
{
    //We can work with repositories instead of DbContext
    var taskRepository = LocalIocManager.Resolve&lt;ITaskRepository&gt;();

    //Obtain test data
    var isaacAsimov = GetPerson(&quot;Isaac Asimov&quot;);
    var thomasMore = GetPerson(&quot;Thomas More&quot;);
    var targetTask = taskRepository.FirstOrDefault(t =&gt; t.AssignedPersonId == isaacAsimov.Id);
    targetTask.ShouldNotBe(null);

    //Run SUT
    _taskAppService.UpdateTask(
        new UpdateTaskInput
        {
            TaskId = targetTask.Id,
            AssignedPersonId = thomasMore.Id
        });

    //Check result
    taskRepository.Get(targetTask.Id).AssignedPersonId.ShouldBe(thomasMore.Id);
}</pre>

<p>In this test, I used <strong>ITaskRepository</strong> to perform database operations, instead of directly working with DbContext. You can use one or mix of these approaches.</p>

<h2 id="ArticleTestAsync">Testing async methods</h2>

<p>We can also test <strong>async</strong> methods with xUnit. See the method written to test <strong>GetAllPeople</strong> method of <strong>PersonAppService</strong>. GetAllPeople method is async, so, testing method should be also async:</p>

<pre>
[Fact]
public async Task Should_Get_All_People()
{
    var output = await _personAppService.GetAllPeople();
    output.People.Count.ShouldBe(4);
}</pre>

<h2 id="ArticleSourceCode">Source Code</h2>

<p>You can get the latest source code here <a href="https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/SimpleTaskSystem"> https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/SimpleTaskSystem</a></p>

<h2 id="ArticleSummary">Summary</h2>

<p>In this article, I wanted to show simply testing projects developed upon ASP.NET Boilerplate application framework. ASP.NET Boilerplate provides a good infrastructure to implement test driven development, or simply creating some unit/integration tests for your applications.</p>

<p>Effort library provides a fake database that works well with EntityFramework. It works as long as you use EntityFramework and LINQ to perform database operations. If you have a stored procedure and want to test it, Effort does not work. For such cases, I recommend using LocalDB.</p>

<p class="abp-invisible">Use the following links for more information on ASP.NET Boilerplate:</p>

<ul class="abp-invisible">
	<li>Official site and documentation: <a href="https://www.aspnetboilerplate.com/">aspnetboilerplate.com</a></li>
	<li>GitHub repositories: <a href="https://github.com/aspnetboilerplate">github.com/aspnetboilerplate</a></li>
	<li>Follow on twitter: <a href="https://twitter.com/aspboilerplate"> @aspboilerplate</a></li>
</ul>

<h2 id="ArticleHistory" class="abp-invisible">Article History</h2>

<ul class="abp-invisible">
	<li>2018-02-22
	<ul>
		<li>Upgraded to ABP v3.4.</li>
	</ul>
	<li>2017-06-28
	<ul>
		<li>Upgraded source code to ABP v2.1.3.</li>
	</ul>
	</li>
	<li>2016-07-19
	<ul>
		<li>Upgraded article and source code for ABP v0.10 release.</li>
	</ul>
	</li>
	<li>2016-01-07
	<ul>
		<li>Upgraded solution to .Net Framework 4.5.2.</li>
		<li>Upgraded Abp to v0.7.7.1.</li>
	</ul>
	</li>
	<li>2015-06-15
	<ul>
		<li>Updated sample project and article based on latest ABP version.</li>
	</ul>
	</li>
	<li>2015-02-02
	<ul>
		<li>First publish of the article.</li>
	</ul>
	</li>
</ul>